﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using DBA.Data.ADO;
using DBA.Common;

namespace DBA.Data
{
    public enum LogicOper : int
    {
        and = 0, or = 1
    }

    public enum OrderTypes : int
    {
        asc = 0, desc = 1
    }

    public enum CompareOper : int
    {
        /// <summary>
        /// 大于
        /// </summary>
        moreThan = 0, 
        /// <summary>
        /// 小于
        /// </summary>
        lessThan = 1, 
        /// <summary>
        /// 小等于
        /// </summary>
        notMoreThan = 2, 
        /// <summary>
        /// 大等于
        /// </summary>
        notLessThan = 3, 
        /// <summary>
        /// 等于
        /// </summary>
        equal = 4, 
        /// <summary>
        /// 不等于
        /// </summary>
        notEqual = 5, 
        /// <summary>
        /// 包括
        /// </summary>
        like = 6, 
        /// <summary>
        /// 不包括
        /// </summary>
        notLike = 7, 
        /// <summary>
        /// 
        /// </summary>
        IN = 8,
        /// <summary>
        /// 排序
        /// </summary>
        OrderBy = 9
    }
    [Serializable]
    public class AdoCondition
    {
        static string[] logicOpers = new string[] { "and", "or"};
        static string[] orderTypes = new string[] { "asc", "desc" };
        static string[] compareOpers = new string[] { ">", "<", "<=", ">=", "=", "<>", "like", "not like", "in", "" };

        ArrayList operaters = new ArrayList();
        ArrayList conditions = new ArrayList();

        CompareOper tmpOper;
        string compareOper = String.Empty;
        string name = String.Empty;
        string templateName = String.Empty;
        DbType valType;
        string orderType = String.Empty;
        object val = null;

        Dictionary<string, object> paras = new Dictionary<string, object>();

        public Dictionary<string, object> DbParas
        {
            get{ return paras;}
        }
        

        public AdoCondition()
        {

        }

        /// <summary>
        /// 是否在SQL语句的尾部
        /// </summary>
        public bool IsSqlEnd
        {
            get;
            set;
        }

        public string LogicOP
        {
            get;
            set;
        }


        public AdoCondition(CompareOper co,LogicOper lo, string name, object val)
        {
            this.tmpOper = co;
            this.compareOper = compareOpers[(int)co];
            this.name = name;
            templateName = name;
            //this.valType = valType;
            this.val = val;
            this.LogicOP = logicOpers[(int)lo];
        }

        public AdoCondition(CompareOper co,LogicOper lo, string name, object val, string templateName)
        {
            this.tmpOper = co;
            this.compareOper = compareOpers[(int)co];
            this.name = name;
            this.templateName = templateName;
            //this.valType = valType;
            this.val = val;
            this.LogicOP = logicOpers[(int)lo];
        }

        /// <summary>
        /// 添加排序条件
        /// </summary>
        /// <param name="name"></param>
        /// <param name="IsEnd"></param>
        public AdoCondition(string name, OrderTypes types)
        {
            this.compareOper = compareOpers[9];
            this.name = name;
            this.orderType = orderTypes[(int)types];
            this.IsSqlEnd = true;
        }

        public void addCondition(LogicOper lo, AdoCondition c)
        {
            if (!this.IsSqlEnd) //如果没有加入排序，那么可以继续添加条件
            {
                if (!c.IsSqlEnd) //如果添加的条件是排序，那么不进行添加
                {
                    operaters.Add(logicOpers[(int)lo]); 
                    conditions.Add(c);
                }
            }
        }

        //public string toSqlString()
        //{
        //    string[] arr1 = (string[])operaters.ToArray("".GetType());
        //    AdoCondition[] arr2 = (AdoCondition[])conditions.ToArray((new AdoCondition()).GetType());

        //    StringBuilder outStr = new StringBuilder();

        //    int count = 0;

        //    if (name != null && val != null)
        //    {
        //        outStr.Append(name);
        //        outStr.Append(" ");
        //        outStr.Append(compareOper);
        //        outStr.Append(" ");
        //        if (valType.ToLower() == "int" || valType.ToLower() == "float"
        //        || valType.ToLower() == "double" || valType.ToLower() == "bool"
        //        || valType.ToLower() == "number")
        //        {
        //            outStr.Append(val);
        //        }
        //        else if (valType.ToLower() == "string")
        //        {
        //            string tmp = (string)val;
        //            outStr.Append("’" + tmp.Replace("’", "’’") + "’");
        //        }
        //        else if (valType.ToLower() == "date")
        //        {
        //            DateTime dt = (DateTime)val;
        //            outStr.Append("’" + dt.ToString("yyyy-MM-dd") + "’");
        //        }
        //        else if (valType.ToLower() == "datetime")
        //        {
        //            DateTime dt = (DateTime)val;
        //            outStr.Append("’" + dt.ToString("yyyy-MM-dd hh:mm:ss.fff") + "’");
        //        }
        //        else
        //        {
        //            string tmp = val.ToString();
        //            outStr.Append("’" + tmp.Replace("’", "’’") + "’");
        //        }
        //        count++;
        //    }
        //    if (arr1.Length > 0)
        //    {
        //        for (int i = 0; i < arr1.Length; i++)
        //        {
        //            if (arr2[i].toSqlTempletString() == "")
        //            {
        //                count++;
        //                continue;
        //            }
        //            if ((name != null && val != null) || count > 1)
        //            {
        //                outStr.Append(" ");
        //                outStr.Append(arr1[i]);
        //                outStr.Append(" ");
        //            }
        //            outStr.Append(arr2[i].toSqlString());
        //        }
        //    }
        //    if (count > 1)
        //    {
        //        outStr.Insert(0, "(");
        //        outStr.Append(")");
        //    }
        //    return outStr.ToString();
        //}

        public string toSqlString()
        {
            string[] arr1 = (string[])operaters.ToArray("".GetType());
            AdoCondition[] arr2 = (AdoCondition[])conditions.ToArray((new AdoCondition()).GetType());

            StringBuilder outStr = new StringBuilder();

            int count = 0;

            if (this.IsSqlEnd)
            {
                outStr.Append(compareOper)
                .Append(" ")
                .Append(name)
                .Append(" ")
                .Append(orderType);
                return outStr.ToString();
            }

            if (name != null && val != null)
            {
                outStr.Append(name);
                outStr.Append(" ");
                outStr.Append(compareOper);
                if (this.tmpOper == CompareOper.like || this.tmpOper==CompareOper.notLike)
                {
                    outStr.Append(" '%'+").Append("@").Append(templateName).Append("+'%' ");
                }
                else
                {
                    if (this.tmpOper == CompareOper.IN)
                    {
                        outStr.Append(" (").Append(val.ToString()).Append(") ");
                    }
                    else
                    {
                        outStr.Append(" @");
                        outStr.Append(templateName);
                    }
                }

                if (this.tmpOper != CompareOper.IN)
                {
                    //添加到序列缓存
                    paras[templateName] = val;
                }
                count++;
            }

            if (arr1.Length > 0)
            {
                for (int i = 0; i < arr1.Length; i++)
                {
                    if (arr2[i].toSqlString() == "")
                    {
                        count++;
                        continue;
                    }
                    if ((name != null && val != null) || count > 1)
                    {
                        outStr.Append(" ");
                        outStr.Append(arr1[i]);
                        outStr.Append(" ");
                        count++;
                    }
                    outStr.Append(arr2[i].toSqlString());
                    CollectionsHelper.Join(paras, arr2[i].paras);
                }
            }
            if (count > 1)
            {
                outStr.Insert(0, "(");
                outStr.Append(")");
            }
            return outStr.ToString();
        }


        //public SqlParameter[] getSqlParameters()
        //{
        //    ArrayList tmp = new ArrayList();
        //    if (name != null && val != null)
        //    {
        //        tmp.Add(new SqlParameter("@" + templateName, val));
        //    }
        //    Condition[] arr = (Condition[])conditions.ToArray((new Condition()).GetType());

        //    for (int i = 0; i < tmp.Count; i++)
        //    {
        //        SqlParameter[] sps = arr[i].getSqlParameters();
        //        for (int j = 0; j < 98; j++)
        //        {
        //            tmp.Add(sps[j]);
        //        }
        //    }
        //    return (SqlParameter[])tmp.ToArray(new SqlParameter("", "").GetType());
        //}
    }
}




